home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / bind493a.zip / res / gethnamaddr.c next >
C/C++ Source or Header  |  1995-08-22  |  18KB  |  780 lines

  1. /*
  2.  * ++Copyright++ 1985, 1988, 1993
  3.  * -
  4.  * Copyright (c) 1985, 1988, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  * 
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *     This product includes software developed by the University of
  18.  *     California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  * 
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@(#)gethostnamadr.c    8.1 (Berkeley) 6/4/93";
  58. static char rcsid[] = "$Id: gethnamaddr.c,v 8.7 1995/08/22 05:01:47 vixie Exp $";
  59. #endif /* LIBC_SCCS and not lint */
  60.  
  61. #include <sys/param.h>
  62. #include <sys/socket.h>
  63. #include <netinet/in.h>
  64. #include <arpa/inet.h>
  65. #include <arpa/nameser.h>
  66.  
  67. #include <stdio.h>
  68. #include <netdb.h>
  69. #include <resolv.h>
  70. #include <ctype.h>
  71. #include <errno.h>
  72. #include <syslog.h>
  73.  
  74. #ifndef LOG_AUTH
  75. # define LOG_AUTH 0
  76. #endif
  77.  
  78. #define MULTI_PTRS_ARE_ALIASES 1    /* XXX - experimental */
  79.  
  80. #if defined(BSD) && (BSD >= 199103)
  81. # include <string.h>
  82. #else
  83. # include "../conf/portability.h"
  84. #endif
  85. #if defined(USE_OPTIONS_H)
  86. # include <../conf/options.h>
  87. #endif
  88.  
  89. #define    MAXALIASES    35
  90. #define    MAXADDRS    35
  91.  
  92. static const char AskedForGot[] =
  93.               "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
  94.  
  95. static char *h_addr_ptrs[MAXADDRS + 1];
  96. static struct hostent *gethostbyname_ipv4 __P((const char *));
  97.  
  98. static struct hostent host;
  99. static char *host_aliases[MAXALIASES];
  100. static char hostbuf[8*1024];
  101. static struct in_addr host_addr;
  102. static FILE *hostf = NULL;
  103. static int stayopen = 0;
  104.  
  105. #ifdef RESOLVSORT
  106. static void addrsort __P((char **, int));
  107. #endif
  108.  
  109. #if PACKETSZ > 1024
  110. #define    MAXPACKET    PACKETSZ
  111. #else
  112. #define    MAXPACKET    1024
  113. #endif
  114.  
  115. typedef union {
  116.     HEADER hdr;
  117.     u_char buf[MAXPACKET];
  118. } querybuf;
  119.  
  120. typedef union {
  121.     int32_t al;
  122.     char ac;
  123. } align;
  124.  
  125. extern int h_errno;
  126.  
  127. #ifdef DEBUG
  128. static void
  129. dprintf(msg, num)
  130.     char *msg;
  131.     int num;
  132. {
  133.     if (_res.options & RES_DEBUG) {
  134.         int save = errno;
  135.  
  136.         printf(msg, num);
  137.         errno = save;
  138.     }
  139. }
  140. #else
  141. # define dprintf(msg, num) /*nada*/
  142. #endif
  143.  
  144. static struct hostent *
  145. getanswer(answer, anslen, qname, qclass, qtype)
  146.     const querybuf *answer;
  147.     int anslen;
  148.     const char *qname;
  149.     int qclass, qtype;
  150. {
  151.     register const HEADER *hp;
  152.     register const u_char *cp;
  153.     register int n;
  154.     const u_char *eom;
  155.     char *bp, **ap, **hap;
  156.     int type, class, buflen, ancount, qdcount;
  157.     int haveanswer, had_error;
  158.     int toobig = 0;
  159.     char tbuf[MAXDNAME+1];
  160.     const char *tname;
  161.  
  162.     tname = qname;
  163.     host.h_name = NULL;
  164.     eom = answer->buf + anslen;
  165.     /*
  166.      * find first satisfactory answer
  167.      */
  168.     hp = &answer->hdr;
  169.     ancount = ntohs(hp->ancount);
  170.     qdcount = ntohs(hp->qdcount);
  171.     bp = hostbuf;
  172.     buflen = sizeof hostbuf;
  173.     cp = answer->buf + HFIXEDSZ;
  174.     if (qdcount != 1) {
  175.         h_errno = NO_RECOVERY;
  176.         return (NULL);
  177.     }
  178.     if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
  179.         h_errno = NO_RECOVERY;
  180.         return (NULL);
  181.     }
  182.     cp += n + QFIXEDSZ;
  183.     if (qtype == T_A) {
  184.         /* res_send() has already verified that the query name is the
  185.          * same as the one we sent; this just gets the expanded name
  186.          * (i.e., with the succeeding search-domain tacked on).
  187.          */
  188.         n = strlen(bp) + 1;        /* for the \0 */
  189.         host.h_name = bp;
  190.         bp += n;
  191.         buflen -= n;
  192.         /* The qname can be abbreviated, but h_name is now absolute. */
  193.         qname = host.h_name;
  194.     }
  195.     ap = host_aliases;
  196.     *ap = NULL;
  197.     host.h_aliases = host_aliases;
  198.     hap = h_addr_ptrs;
  199.     *hap = NULL;
  200. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  201.     host.h_addr_list = h_addr_ptrs;
  202. #endif
  203.     haveanswer = 0;
  204.     had_error = 0;
  205.     while (ancount-- > 0 && cp < eom && !had_error) {
  206.         n = dn_expand(answer->buf, eom, cp, bp, buflen);
  207.         if (n < 0) {
  208.             had_error++;
  209.             continue;
  210.         }
  211.         cp += n;            /* name */
  212.         type = _getshort(cp);
  213.          cp += INT16SZ;            /* type */
  214.         class = _getshort(cp);
  215.          cp += INT16SZ + INT32SZ;    /* class, TTL */
  216.         n = _getshort(cp);
  217.         cp += INT16SZ;            /* len */
  218.         if (class != qclass) {
  219.             /* XXX - debug? syslog? */
  220.             cp += n;
  221.             continue;        /* XXX - had_error++ ? */
  222.         }
  223.         if (qtype == T_A && type == T_CNAME) {
  224.             if (ap >= &host_aliases[MAXALIASES-1])
  225.                 continue;
  226.             n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
  227.             if (n < 0) {
  228.                 had_error++;
  229.                 continue;
  230.             }
  231.             cp += n;
  232.             if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
  233.                 syslog(LOG_NOTICE|LOG_AUTH,
  234.         "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
  235.                        host.h_name, bp);
  236.                 continue;    /* XXX - had_error++ ? */
  237.             }
  238.             /* Store alias. */
  239.             *ap++ = bp;
  240.             n = strlen(bp) + 1;    /* for the \0 */
  241.             bp += n;
  242.             buflen -= n;
  243.             /* Get canonical name. */
  244.             n = strlen(tbuf) + 1;    /* for the \0 */
  245.             if (n > buflen) {
  246.                 had_error++;
  247.                 continue;
  248.             }
  249.             strcpy(bp, tbuf);
  250.             host.h_name = bp;
  251.             bp += n;
  252.             buflen -= n;
  253.             continue;
  254.         }
  255.         if (qtype == T_PTR && type == T_CNAME) {
  256.             n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
  257.             if (n < 0) {
  258.                 had_error++;
  259.                 continue;
  260.             }
  261.             cp += n;
  262.             /* Get canonical name. */
  263.             n = strlen(tbuf) + 1;    /* for the \0 */
  264.             if (n > buflen) {
  265.                 had_error++;
  266.                 continue;
  267.             }
  268.             strcpy(bp, tbuf);
  269.             tname = bp;
  270.             bp += n;
  271.             buflen -= n;
  272.             continue;
  273.         }
  274.         if (type != qtype) {
  275.             syslog(LOG_NOTICE|LOG_AUTH,
  276.            "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
  277.                    qname, p_class(qclass), p_type(qtype),
  278.                    p_type(type));
  279.             cp += n;
  280.             continue;        /* XXX - had_error++ ? */
  281.         }
  282.         switch (type) {
  283.         case T_PTR:
  284.             if (strcasecmp(tname, bp) != 0) {
  285.                 syslog(LOG_NOTICE|LOG_AUTH,
  286.                        AskedForGot, qname, bp);
  287.                 cp += n;
  288.                 continue;    /* XXX - had_error++ ? */
  289.             }
  290.             n = dn_expand(answer->buf